/**
 * 
 */
package jmath.function.meta;

import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Volume {
	protected Log log = LogFactory.getLog(Volume.class);

	protected List<Dot> dotList;	

	protected Dot minValueDot;
	
	private Map<String, Interval> paramIntervalMap;
	
	public String toString(){
		return (minValueDot!=null?(minValueDot.getResultValue()+":"):"")
		+(paramIntervalMap!=null?paramIntervalMap+":":"");
	}
	
	public Interval getParamInterval(String paramName){
		return paramIntervalMap.get(paramName);
	}	
	
	public void putParamInterval(String param, Interval interval) {
		paramIntervalMap.put(param, interval);
	}
	

	public Volume() {
		paramIntervalMap = new HashMap<String, Interval>();		
		dotList = new ArrayList<Dot>();		
	}

	public synchronized Volume half() {
		
		for(String paramName:paramIntervalMap.keySet()){
			double value = minValueDot.getParamValueMap().get(paramName);
			paramIntervalMap.put(paramName,new Interval(value,value));			
		}
		
		
		Map<Integer,Dot> dotMap = new HashMap<Integer,Dot>();
		Map<Integer,Double> destinationMap = new HashMap<Integer,Double>();
		int index=1;		
		for (Dot dot : dotList) {
			dotMap.put(index,dot);
			destinationMap.put(index,dot.getResultValue());			
			index=index+1;
		}
		
		List<Double> destinationList = new ArrayList<Double>(destinationMap.values());
		
		Collections.sort(destinationList);
		
		
		dotList = new ArrayList<Dot>();
		
		destinationList=destinationList.subList(0, destinationList.size()/2);
		
		for (Double destination :destinationList) {			
			for(Integer index_:destinationMap.keySet()){
				if(destinationMap.get(index_)==destination){
					putDot(dotMap.get(index_));					
				}
			}			
		}
		
		return this;
	}

	public synchronized Dot getMinValueDot() {
		return minValueDot;
	}
	
	public synchronized List<Dot> getDotList() {
		return Collections.unmodifiableList(dotList);
	}

	public synchronized void addDot(Dot dot) {
		if (minValueDot == null
				|| (minValueDot.getResultValue() > dot.getResultValue())) {
			minValueDot = dot;
		}		
		dotList.add(dot);
	}
	
	public void initParamValueMap(Map<String, Double> currentParamValueMap) {		
		for (String paramName : paramIntervalMap.keySet()) {
			currentParamValueMap.put(paramName, paramIntervalMap.get(paramName)
					.getRandomValue());
		}		
	}
	
	private synchronized void putDot(Dot dot) {
		for(String paramName:paramIntervalMap.keySet()){			
			paramIntervalMap.get(paramName).resizeInterval(dot.getParamValueMap().get(paramName));			
		}
		addDot(dot);
	}

	public Map<String, Interval> getParamIntervalMap() {
		return paramIntervalMap;
	}
	

}
